package View;


import Controller.Beat.BeatController;
import Controller.Heart.*;
import Model.Beat.BeatModel;
import Model.Beat.BeatModelInterface;
import Model.Heart.HeartModel;
import Model.Heart.HeartModelInterface;
import View.Beat.* ; 
import Model.Game.* ; 
import Controller.Game.* ; 

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class DJView implements ActionListener,  BeatObserver, BPMObserver {
	BeatModelInterface model;
	CircleBar Cir;
	ControllerInterface controller;
    JFrame viewFrame;
    JPanel viewPanel;
    JPanel timerPanel;
	BeatBar beatBar;
	JLabel bpmOutputLabel;
	JLabel timerOutputLabel;
    JFrame controlFrame;
    JPanel controlPanel;
    JLabel bpmLabel;
    JTextField bpmTextField;
    JButton setBPMButton;
    JButton increaseBPMButton;
    JButton decreaseBPMButton;
    JMenuBar menuBar;
    JMenuBar menuBarBeatBar ; 
    JMenu menu;
    JPanel F;
    JLayeredPane L;
    JMenu menuBeatBar ; 
    JMenuItem beatBarMenuItem ; 
    JMenuItem heartBarMenuItem ; 
    JMenuItem gameMenuItem ; 
    JMenuItem startMenuItem;
    JMenuItem stopMenuItem;
    static boolean cirOrBeat = false ; 
    int xBeatBar ;

    public DJView(ControllerInterface controller, BeatModelInterface model) {	
		this.controller = controller;
		this.model = model;
		model.registerObserver((BeatObserver)this);
		model.registerObserver((BPMObserver)this);
    }

    public void createView() {
    	
		        viewPanel = new JPanel(new GridLayout(1,2));
        viewFrame = new JFrame("View");
        viewFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
        JPanel bpmPanel = new JPanel(new GridLayout(2, 1));
        menuBarBeatBar = new JMenuBar() ; 
        menuBeatBar = new JMenu("Model") ;
        beatBarMenuItem = new JMenuItem("BeatModel");
        menuBeatBar.add(beatBarMenuItem);
        beatBarMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
            	viewFrame.dispose() ; 
            	controlFrame.dispose(); 
            	controller.stop() ; 
            	model = new BeatModel() ;
            	controller = new BeatController(model) ; 
            }
        });
        heartBarMenuItem = new JMenuItem("HeartModel");
        menuBeatBar.add(heartBarMenuItem); 
        heartBarMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
            	viewFrame.dispose() ;
            	controlFrame.dispose(); 
            	controller.stop() ; 
            	HeartModelInterface heart = HeartModel.getInstance();
            	model = new HeartAdapter(heart) ; 
            	controller = new HeartController(heart);	
            }
        });
        gameMenuItem = new JMenuItem("GameModel");
        menuBeatBar.add(gameMenuItem)  ;
        gameMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
            	viewFrame.dispose() ; 
            	controlFrame.dispose() ; 
            	controller.stop() ; 
            	model = new GameModel() ; 
            	controller = new GameController(model) ; 
            	}
        });
        JMenuItem gameMenuItemNewView = new JMenuItem("GameModel (New View) ") ;
        menuBeatBar.add(gameMenuItemNewView) ;
        gameMenuItemNewView.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent event) {
            	viewFrame.dispose(); 
        		controlFrame.dispose()  ; 
        		controller.stop() ; 
        		model = new GameModel() ; 
        		cirOrBeat = true ;  
            	controller = new GameController(model) ; 		
        	}
        }) ;
        menuBarBeatBar.add(menuBeatBar);
        viewFrame.setJMenuBar(menuBarBeatBar);
        

        
        if(controller instanceof GameController){
        	timerOutputLabel = new JLabel("Time left: 10 seg.", SwingConstants.CENTER);
        	bpmOutputLabel = new JLabel("Current Clicks: 0", SwingConstants.CENTER);
        	bpmPanel.setLayout(new GridLayout (3,1) );
        	bpmPanel.add(timerOutputLabel) ;
        }
        else{
        	bpmOutputLabel = new JLabel("offline", SwingConstants.CENTER);
        }
       
        viewFrame.getContentPane().add(viewPanel, BorderLayout.CENTER);
        if (cirOrBeat==true){
        	Cir = new CircleBar() ;
        	bpmPanel.setLayout(new GridLayout (2,1) );
        	bpmPanel.add(bpmOutputLabel);
        	viewPanel.add(bpmPanel);
        	viewPanel.add(Cir) ; 
        	viewFrame.setSize(new Dimension(350,250));  
        	xBeatBar = 350 ; 
            cirOrBeat = false ;
        } else {
        	beatBar = new BeatBar();
        	beatBar.setValue(0);
			bpmPanel.add(beatBar);
			bpmPanel.add(bpmOutputLabel);
        	viewPanel.add(bpmPanel);
	        viewFrame.pack();
	        xBeatBar = (int) viewFrame.getSize().getWidth();
	    }
        viewFrame.setVisible(true);
	}
  
  
    public void createControls() {
		// Create all Swing components here
        controlFrame = new JFrame("Control");
        controlFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        controlFrame.setSize(new Dimension(100, 80));
        controlFrame.setLocation(xBeatBar,0);

        controlPanel = new JPanel(new GridLayout(1, 2));

        menuBar = new JMenuBar();
        menu = new JMenu("DJ Control");
        startMenuItem = new JMenuItem("Start");
        menu.add(startMenuItem);
        startMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                controller.start();
            }
        });
        stopMenuItem = new JMenuItem("Stop");
        menu.add(stopMenuItem); 
        stopMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                controller.stop();
            }
        });
        JMenuItem exit = new JMenuItem("Quit");
        exit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                System.exit(0);
            }
        });

        menu.add(exit);
        menuBar.add(menu);
        controlFrame.setJMenuBar(menuBar);

        bpmTextField = new JTextField(2);
        bpmLabel = new JLabel("Enter BPM:", SwingConstants.RIGHT);
        
        if(controller instanceof GameController) {
        	decreaseBPMButton = new JButton("Reset");
        	setBPMButton = new JButton("Click Me");}
        else{
        	decreaseBPMButton = new JButton("<<");
        	setBPMButton = new JButton("Set");}
        setBPMButton.setSize(new Dimension(10,40));
        increaseBPMButton = new JButton(">>");
        
        setBPMButton.addActionListener(this);
        increaseBPMButton.addActionListener(this);
        decreaseBPMButton.addActionListener(this);

        JPanel buttonPanel = new JPanel(new GridLayout(1, 2));

		buttonPanel.add(decreaseBPMButton);
		buttonPanel.add(increaseBPMButton);

        JPanel enterPanel = new JPanel(new GridLayout(1, 2));
        enterPanel.add(bpmLabel);
        enterPanel.add(bpmTextField);
        JPanel insideControlPanel = new JPanel(new GridLayout(3, 1));
        insideControlPanel.add(enterPanel);
        insideControlPanel.add(setBPMButton);
        insideControlPanel.add(buttonPanel);
        controlPanel.add(insideControlPanel);
        
        bpmLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
        bpmOutputLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));

        controlFrame.getRootPane().setDefaultButton(setBPMButton);
        controlFrame.getContentPane().add(controlPanel, BorderLayout.CENTER);

        controlFrame.pack();
        controlFrame.setVisible(true);
    }

	public void enableStopMenuItem() {
    	stopMenuItem.setEnabled(true);
	}

	public void disableStopMenuItem() {
    	stopMenuItem.setEnabled(false);
	}

	public void enableStartMenuItem() {
    	startMenuItem.setEnabled(true);
	}

	public void disableStartMenuItem() {
    	startMenuItem.setEnabled(false);
	}

    public void actionPerformed(ActionEvent event) {
		if (event.getSource() == setBPMButton) {
			if(controller instanceof GameController)
			{
				((GameController)controller).increaseBPM();			
			}
		else{
			int bpm = Integer.parseInt(bpmTextField.getText());
        	controller.setBPM(bpm);}
		} else if (event.getSource() == increaseBPMButton) {			
				controller.increaseBPM();
		} else if (event.getSource() == decreaseBPMButton) {
			if(controller instanceof GameController)
				((GameController)controller).reset();
			else
				controller.decreaseBPM();
		}
    }

	public void updateBPM() {
		if (model != null) {
			int bpm = model.getBPM();
			if (bpm == 0) {
				if (bpmOutputLabel != null) {

					if( this.controller instanceof GameController){
						bpmOutputLabel.setText("Current Clicks: 0");
		    			}
					else
        			bpmOutputLabel.setText("offline");
				}
			} else {
				if (bpmOutputLabel != null) {
					
					if( this.controller instanceof GameController){
						timerOutputLabel.setText("Time Left: " + ((GameModel)model).getCurrentTime() + " seg.");
						bpmOutputLabel.setText("Current clicks: " + model.getBPM());
		    			}
					else if ( this.controller instanceof HeartController){
						if( HeartModel.getTries() == 0 ) {
							bpmOutputLabel.setText("Heart rate:  " + model.getBPM());
						}	else { 
							bpmOutputLabel.setText("Instantiation tries: " + HeartModel.getTries() ); 
						}
					} else {
					    bpmOutputLabel.setText("Current BPM: " + model.getBPM());
					}
				}
			}
		}
	}
  
	public void updateBeat() {
		if (beatBar != null) {
			 beatBar.setValue(100);
			 
		}
		if(Cir != null)
		{
			Cir.setValue(-70);
		}
	}

}
